#include "editordefase.h"
#include <QDebug>
#include "enums.h"
#include "exception.h"
#include "faseio.h"

EditorDeFase::EditorDeFase(QPixmap *imagemFasePixmap):
    contadorCaixa(0),
    contadorPontoX(0),
    contadorHeroi(0),
    _imagemFasePixmap(imagemFasePixmap),
    _elementoDeFase(new ElementoDeFase),
     painter(new QPainter(this->_imagemFasePixmap)),
    _hashElementosDaFase(QHash<PontoHash, editacao::Elementos>())
{
    this->_hashElementosDaFase.reserve(150);
}

EditorDeFase::~EditorDeFase()
{
    delete this->_imagemFasePixmap;
    delete this->_elementoDeFase;
}

QPixmap *EditorDeFase::imagemFasePixmap()const
{
    return this->_imagemFasePixmap;
}

ElementoDeFase *EditorDeFase::elementoDeFase()const
{
    return this->_elementoDeFase;
}

QPoint EditorDeFase::pontoDeRepaint()const
{
    return this->_pontoDeRapaint;
}

void EditorDeFase::setElementoDeFase(const ElementoDeFase &elementoDeFase)
{
    *this->_elementoDeFase = elementoDeFase;
}

void EditorDeFase::setPontoDeRepaint(const QPoint &pontoDeRepaint)
{
    this->_pontoDeRapaint = PontoHash(pontoDeRepaint);
}

void EditorDeFase::atualizaFase()
{
    if(this->_elementoDeFase->elemento() == editacao::NONE) throw Exception("Nenhum Elemento de Fase Escolhido.\nPor favor escolha um dos elementos ao lado");
    if(this->_elementoDeFase->elemento() == editacao::HEROI && this->contadorHeroi == 1) throw Exception("Apenas um lugar para o personagem iniciar a partida permitido.\n Se quiser mudar esse lugar, por favor, subistitua a posicao atual por um elemento de chao");

    this->atualizaHashElementos();
    this->painter->drawImage(this->_pontoDeRapaint, this->_elementoDeFase->imagemElementoDeFase());

}

void EditorDeFase::salvar(QString &path)
{
    try{
        this->montarFase();
        FaseIO(path).salvar(*this->fase);
    }catch(Exception e){
        QString msg = e.msg();
        throw Exception(msg);
    }
}

void EditorDeFase::montarFase()
{
    if (this->contadorCaixa != this->contadorPontoX)
    {
        throw Exception ("O numero de caixas nao estah compativel com o numero de pontos X onde a caixa deve ser inserida afim de comletar a fase.");
    }

    QImage imagemFase = this->_imagemFasePixmap->toImage();
    this->fase = new Fase(imagemFase, &this->_hashElementosDaFase, this->contadorPontoX);
    this->fase->setPontoPartida(this->pontoHeroi);
}

void EditorDeFase::atualizaHashElementos()
{
    if(this->_hashElementosDaFase.contains(this->_pontoDeRapaint))
    {
        editacao::Elementos elementoLocal = this->_hashElementosDaFase.take(this->_pontoDeRapaint);

        switch(elementoLocal)
        {
            case editacao::CAIXA:
                this->contadorCaixa--;
                break;
            case editacao::PONTOX:
                this->contadorPontoX--;
                break;
            case editacao::HEROI:
                this->contadorHeroi = 0;
                break;
            default:
                break;
        }
    }

    if(this->_elementoDeFase->elemento() != editacao::CHAO)
    {
        if(this->_elementoDeFase->elemento() != editacao::HEROI) this->_hashElementosDaFase[this->_pontoDeRapaint] = this->_elementoDeFase->elemento();

        editacao::Elementos elementoLocal = this->_elementoDeFase->elemento();
        switch(elementoLocal)
        {
            case editacao::CAIXA:
                this->contadorCaixa++;
                break;
            case editacao::PONTOX:
                this->contadorPontoX++;
                break;
            case editacao::HEROI:
                this->contadorHeroi = 1;
                this->pontoHeroi = this->_pontoDeRapaint;
                break;
            default:
                break;
        }
    }
}
